<script setup lang="ts">
  import Editor from '@/components/business/editor/Editor.vue'
  import { computed, nextTick, ref, watch } from 'vue'
  import { fileUpload } from '@/api/upload'
  import type { UploadFile, FormInstance, UploadRawFile } from 'element-plus'
  import {
    ElForm,
    ElFormItem,
    ElInput,
    ElRadioGroup,
    ElRadio,
    ElUpload,
    ElIcon,
    ElTable,
    ElTableColumn,
    ElSelect,
    ElOption,
  } from 'element-plus'
  import { useManualForm, useGetManualInfo } from '@/services/pages/know/useManual'
  import { useGetGoodListByManualId } from '@/services/pages/good/useGood'
  import { UploadFilled } from '@element-plus/icons-vue'
  import { HMessage, HMessageBox } from '@/components/common/message'
  import { Good } from './types'
  import GoodSelectModal from '@/components/business/good-select-modal/GoodSelectModal.vue'

  const { form, formSaveLoading, formSave, resetForm } = useManualForm()
  const { manualInfo, getInfoLoading, getInfo } = useGetManualInfo()
  const {
    list: goodListByManualId,
    getListLoading: getGoodListLoading,
    getList: getGoodList,
  } = useGetGoodListByManualId()

  defineOptions({
    name: 'ManualFormModal',
  })

  const props = defineProps({
    manualId: {
      type: String,
      default: () => '',
    },
  })

  const emits = defineEmits<{
    (e: 'update'): void
  }>()

  // 弹窗显示状态
  const visible = defineModel('visible', { type: Boolean, default: false })

  // 编辑器组件实例
  const editorInstance = ref<InstanceType<typeof Editor> | null>(null)

  // 表单组件实例
  const formInstance = ref<FormInstance | null>(null)

  // 表单验证
  const rules = ref({
    name: [{ required: true, message: '请输入名称', trigger: ['change', 'blur'] }],
    status: [{ required: true, message: '请选择状态', trigger: ['change', 'blur'] }],
  })

  // 封面文件对象
  const coverFileObj = ref<{ url: string; file: UploadRawFile }>({
    url: '',
    file: null,
  })

  // 产品列表
  const goodList = ref<Array<Good>>([])

  // 产品选择弹窗显示状态
  const goodSelectModalVisible = ref(false)

  // 文件上传加载
  const fileUploadLoading = ref(false)

  // 加载
  const loading = computed(() => {
    return (
      formSaveLoading.value ||
      getInfoLoading.value ||
      fileUploadLoading.value ||
      getGoodListLoading.value
    )
  })

  // 工单列表初始化
  const goodListInit = () => {
    goodList.value = [
      {
        brand: '',
        brandId: null,
        code: '',
        createTime: null,
        goodsType: 1,
        id: '',
        itemNumber: null,
        model: '',
        name: '',
        source: null,
        specName: null,
        status: null,
        type: '',
        typeThree: '',
        typeTwo: '',
        unit: null,
        updateTime: null,
        warrantyDay: null,
        isFixed: true,
      },
    ]
  }

  /**
   * 隐藏抽屉
   */
  const hideDrawer = () => {
    resetForm()
    visible.value = false
  }

  /**
   * 挂载编辑器
   */
  const mountEditor = () => {
    nextTick(() => {
      if (editorInstance.value) {
        editorInstance.value.mountEditor()
      }
    })
  }

  /**
   * 封面上传事件
   * @param {UploadFile} uploadFile - 文件对象
   */
  const onUploadCover = (uploadFile: UploadFile) => {
    if (!uploadFile.raw.type.includes('image')) {
      HMessageBox.error('只能上传图片')
      return false
    }
    if (uploadFile.raw.size / 1024 / 1024 > 50) {
      HMessageBox.error('图片大小不能超过50M!')
      return false
    }
    coverFileObj.value = {
      file: uploadFile.raw,
      url: URL.createObjectURL(uploadFile.raw),
    }
  }

  /**
   * 封面删除事件
   */
  const onDelCover = () => {
    coverFileObj.value = {
      file: null,
      url: '',
    }
    form.value.image = ''
  }

  /**
   * 获取表格行的类名，主要用于给第一行设置一个固定的样式
   * @param {Object} data - 行数据
   * @param {Good} data.row - 产品信息
   * @param {Number} data.rowIndex - 行索引
   */
  const getRowClassName = (data: { row: Good; rowIndex: number }) => {
    if (data.rowIndex === 0) {
      return 'fixed-row'
    }
  }

  /**
   * 产品选择事件
   * @param {Array<NotSpecGoodListItem>} goods - 产品列表
   */
  const handleGoodSelect = (goods: Array<NotSpecGoodListItem>) => {
    goodListInit()
    goods.forEach((good) => {
      goodList.value.push({
        ...good,
        isFixed: false,
      })
    })
  }

  /**
   * 产品删除事件
   * @param {Number} index - 产品索引
   */
  const handleDelGood = (index: number) => {
    goodList.value.splice(index, 1)
  }

  /**
   * 保存事件
   */
  const onSave = async () => {
    if (formInstance.value) {
      try {
        await formInstance.value.validate()
        if (coverFileObj.value.file) {
          const files = [coverFileObj.value.file]
          fileUploadLoading.value = true
          const res = await fileUpload(files)
          fileUploadLoading.value = false
          form.value.image = res.data.data.rows[0]
        }
        if (editorInstance.value) {
          const files = editorInstance.value.getUploadFiles().map((file) => file.file)
          const fileTempUrl = editorInstance.value.getUploadFiles().map((file) => file.tempUrl)
          if (files.length > 0) {
            fileUploadLoading.value = true
            const res = await fileUpload(files)
            fileUploadLoading.value = false
            res.data.data.rows.forEach((fileUrl: string, fileUrlIndex: number) => {
              editorInstance.value.convertTempPathToServerPath(fileTempUrl[fileUrlIndex], fileUrl)
            })
          }
          form.value.content = await editorInstance.value.getEditorValue()
        }
        form.value.productInstrBookVos = goodList.value
          .filter((item) => !!item.id)
          .map((item) => {
            return {
              goodsId: item.id,
              type: item.goodsType,
            }
          })
        const res = await formSave()
        if (res.code === 20000) {
          HMessage.success('保存成功')
          emits('update')
          hideDrawer()
          return
        }
        HMessageBox.error(res.message)
      } catch (error) {
        // error
      }
    }
  }

  watch(
    visible,
    async (value) => {
      if (value) {
        mountEditor()
        goodListInit()

        if (props.manualId) {
          await getInfo(props.manualId)
          await getGoodList(props.manualId)
          goodListByManualId.value.forEach((item) => {
            goodList.value.push({
              isFixed: false,
              brand: '',
              brandId: '',
              code: item.goodsCode,
              id: item.goodsId,
              model: item.goodsModel,
              name: item.goodsName,
              goodsType: item.type,
              createTime: '',
              itemNumber: 0,
              source: 1,
              specName: '',
              status: 1,
              type: '',
              typeThree: '',
              typeTwo: '',
              unit: '',
              updateTime: '',
              warrantyDay: '',
            })
          })
          form.value.name = manualInfo.value.name
          form.value.status = manualInfo.value.status
          form.value.visibilityType = manualInfo.value.visibilityType
          form.value.id = manualInfo.value.id
          form.value.image = manualInfo.value.image
          coverFileObj.value.url = manualInfo.value.image
          form.value.content = manualInfo.value.content
          form.value.productInstrBookVos = manualInfo.value.productInstrBookVos
        }
      }
    },
    { immediate: true },
  )
</script>

<template>
  <h-drawer
    v-model="visible"
    :title="props.manualId ? '编辑说明书' : '创建说明书'"
    :loading="loading"
    :width="1000"
    unit="px"
    @close="hideDrawer"
  >
    <el-form
      ref="formInstance"
      label-position="top"
      :rules="rules"
      :model="form"
      class="modal_form_content"
      inline-message
      style="height: 100%; padding: 0 72px; overflow: auto"
      scroll-to-error
      :scroll-into-view-options="{ behavior: 'smooth' }"
    >
      <!-- 说明书名称 -->
      <el-form-item label="说明书名称" prop="name">
        <el-input v-model.trim="form.name" clearable placeholder="请输入名称" maxlength="20" />
      </el-form-item>

      <!-- 可见类型 -->
      <el-form-item label="可见类型" prop="visibilityType">
        <el-select v-model="form.visibilityType" placeholder="请选择可见类型">
          <el-option :value="1" label="全部可见"></el-option>
          <el-option :value="2" label="网点可见"></el-option>
          <el-option :value="3" label="公司可见"></el-option>
        </el-select>
      </el-form-item>

      <!-- 说明书状态 -->
      <el-form-item label="说明书状态" class="same_line">
        <el-radio-group v-model="form.status" class="el-group">
          <el-radio :value="false" size="small">
            <span>启用</span>
          </el-radio>
          <el-radio :value="true" size="small">
            <span>禁用</span>
          </el-radio>
        </el-radio-group>
      </el-form-item>

      <!-- 封面 -->
      <el-form-item label="封面">
        <el-upload
          v-if="!coverFileObj.url"
          accept="image/*"
          :auto-upload="false"
          :show-file-list="false"
          :on-change="onUploadCover"
          class="cover"
        >
          <el-icon :size="24" color="#007cff">
            <UploadFilled />
          </el-icon>
        </el-upload>
        <h-image v-else :src="coverFileObj.url" :height="70" :width="70" @del="onDelCover">
        </h-image>
      </el-form-item>

      <el-form-item label="产品列表">
        <el-table
          :border="true"
          stripe
          :data="goodList"
          :row-class-name="getRowClassName"
          max-height="400"
        >
          <el-table-column label="序号" :align="'center'" fixed="left" width="50">
            <template #default="{ row, $index }">
              {{ row.isFixed ? '' : $index }}
            </template>
          </el-table-column>
          <el-table-column label="产品名称" prop="name" width="200"></el-table-column>
          <el-table-column label="产品编号" prop="code" width="200"></el-table-column>
          <el-table-column label="产品型号" prop="model" width="200"></el-table-column>
          <el-table-column label="操作" width="100">
            <template #default="{ row, $index }">
              <h-link v-if="row.isFixed" @click="goodSelectModalVisible = true">添加产品</h-link>
              <h-link v-else type="error" @click="handleDelGood($index)">删除</h-link>
            </template>
          </el-table-column>
        </el-table>
      </el-form-item>

      <!-- 说明书内容 -->
      <el-form-item label="内容">
        <Editor
          ref="editorInstance"
          :is-can-upload-video="false"
          :value="form.content"
          :style="{ height: '400px' }"
        ></Editor>
      </el-form-item>
    </el-form>

    <template #footer>
      <HButton is-modal type="primary" @click="onSave">保存</HButton>
      <HButton is-modal @click="hideDrawer">取消</HButton>
    </template>

    <good-select-modal
      v-model:visible="goodSelectModalVisible"
      :good-select-list="goodList.slice(1)"
      @select-good="handleGoodSelect"
    ></good-select-modal>
  </h-drawer>
</template>

<style scoped lang="scss">
  .cover {
    width: 70px;
    height: 70px;
    border: 1px solid #dcdfe6;
    box-sizing: border-box;

    :deep(.el-upload) {
      width: 100%;
      height: 100%;
      display: flex;
      justify-content: center;
      align-items: center;
    }
  }

  :deep(.fixed-row) {
    position: sticky;
    position: -webkit-sticky;
    top: 0;
    z-index: 3;
  }
</style>
